package com.zj.study;

import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;

public class 基本计算器1加减乘除不含括号 {

    public static void main(String[] args) {
        String aa = "1*2*3-3/4+5*6-7*8+9/10";
        System.out.println(calculate(aa.replace(" ", "")));
    }

    public static Integer calculate(String s) {
        Deque<Integer> numeQue = new ArrayDeque<>();
        int res = 0;
        char lastflag = '+';
        Integer num = 0;
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) >= '0' && s.charAt(i) <= '9') {
                num += s.charAt(i) - '0' + num * 10;
            }
            if (s.charAt(i) < '0' || s.charAt(i) > '9' || i == s.length() - 1) {
                if (lastflag == '*') {
                    numeQue.push(numeQue.pop() * num);
                } else if (lastflag == '/') {
                    numeQue.push(numeQue.pop() / num);

                } else if (lastflag == '-') {
                    numeQue.push(-num);
                } else {
                    numeQue.push(num);
                }
                num = 0;
                lastflag = s.charAt(i);
            }
        }
        while (!numeQue.isEmpty()) {
            res += numeQue.pop();
        }
        return res;
    }

    public static boolean isDigit(char ch) {
        return ch >= '0' && ch <= '9';
    }

    public static Integer calculate4(String s) {
        int res = 0;
        String[] split = s.split("[+\\-\\*/]");
        Deque<Integer> numeQue = new ArrayDeque<>();
        int index = 0;
        char lastOpt = '+';
        for (int i = 0; i < split.length; i++) {
            if (lastOpt == '*') {
                numeQue.push(numeQue.pop() * Integer.parseInt(split[i]));
            } else if (lastOpt == '/') {
                numeQue.push(numeQue.pop() / Integer.parseInt(split[i]));

            } else if (lastOpt == '-') {
                numeQue.push(-Integer.parseInt(split[i]));
            } else {
                numeQue.push(Integer.parseInt(split[i]));
            }
            index += split[i].length();
            if ((index + i) < s.length()) {
                lastOpt = s.charAt(index + i);
            }
        }
        while (!numeQue.isEmpty()) {
            res += numeQue.pop();
        }
        return res;
    }

    public static Integer calculate3(String s) {
        String[] split = s.split("[+\\-\\*/]");
        Deque<Character> opQue1 = new ArrayDeque<>();
        Deque<Integer> numeQue = new ArrayDeque<>();
        int index = 0;
        for (int i = 0; i < split.length; i++) {
            numeQue.push(Integer.parseInt(split[i]));
            index += split[i].length();
            while (!opQue1.isEmpty()) {
                boolean isPri = opQue1.peek() == '*' || opQue1.peek() == '/';
                boolean isSec = (index + i) >= s.length() || s.charAt(index + i) == '+' || s.charAt(index + i) == '-';
                if (!isPri && !isSec) {
                    break;
                }
                Character op = opQue1.pop();
                Integer res = compute(numeQue.pop(), numeQue.pop(), op);
                if (res == null) {
                    return null;
                }
                numeQue.push(res);
            }
            if ((index + i) < s.length()) {
                opQue1.push(s.charAt(index + i));
            }
        }
        return numeQue.pop();
    }


    //用了队列和递归，感觉不太好
    public static Integer calculate2(String s, String optrex) {
        String[] split = s.split(optrex);
        Deque<Character> opQue1 = new ArrayDeque<>();
        Deque<Integer> numeQue = new ArrayDeque<>();
        int index = 0;
        for (int i = 0; i < split.length; i++) {
            if (split[i].contains("*") || split[i].contains("/")) {
                Integer res = calculate2(split[i], "[*/]");
                if (res == null) {
                    return null;
                }
                numeQue.push(res);
            } else {
                numeQue.push(Integer.parseInt(split[i]));
            }
            while (!opQue1.isEmpty()) {
                Character op = opQue1.pop();
                Integer res = compute(numeQue.pop(), numeQue.pop(), op);
                if (res == null) {
                    return null;
                }
                numeQue.push(res);

            }
            index += split[i].length();
            if ((index + i) < s.length()) {
                opQue1.push(s.charAt(index + i));
            }
        }
        return numeQue.pop();

    }

    public static Integer compute(int a, int b, char operator) {
        switch (operator) {
            case '+':
                return b + a;
            case '-':
                return b - a;
            case '*':
                return b * a;
            case '/':
                return a == 0 ? null : b / a;
        }
        return null;
    }
}
